﻿using System;
using System.IO;
using System.Security.Cryptography;
using System.Text;

namespace JsPark.AES
{
    class AES
    {

        private RijndaelManaged m_rijAlg = new RijndaelManaged();
        private string m_sPlainText = string.Empty;
        
        private byte[] m_bsKey = null;
        public byte[] Key
        {
            get { return m_bsKey; }
        }
        private byte[] m_bsIv = null;
        public byte[] BsIv
        {
            get { return m_bsIv; }
        }



        public AES()
        {
            this.m_rijAlg.KeySize = 256;
            this.m_rijAlg.GenerateKey();
            this.m_rijAlg.GenerateIV();
            this.m_bsKey = this.m_rijAlg.Key;
            this.m_bsIv = this.m_rijAlg.IV;
        }

        public string getKeyBitsTostring()
        {
            StringBuilder sbTmp = new StringBuilder();
            foreach (byte bs in this.m_bsKey)
            {
                sbTmp.Append(Convert.ToString(bs, 2).PadLeft(8, '0'));
            }
            return sbTmp.ToString();
        }

        public string getKeyBytesTostring()
        {
            StringBuilder sbTmp = new StringBuilder();
            foreach (byte bs in this.m_bsKey)
            {
                sbTmp.Append(bs + " ");
            }
            return sbTmp.ToString();
        }

        public byte[] encryption(string plainText)
        {
            if (plainText == null || plainText.Length <= 0)
                throw new ArgumentNullException("plainText");
            if (m_bsKey == null || m_bsKey.Length <= 0)
                throw new ArgumentNullException("Key");
            if (m_bsIv == null || m_bsIv.Length <= 0)
                throw new ArgumentNullException("Key");
            byte[] encrypted;
            m_rijAlg.Key = m_bsKey;
            m_rijAlg.IV = m_bsIv;
            ICryptoTransform encryptor = m_rijAlg.CreateEncryptor(m_rijAlg.Key, m_rijAlg.IV);
            using (MemoryStream msEncrypt = new MemoryStream())
            {
                using (CryptoStream csEncrypt = new CryptoStream(msEncrypt, encryptor, CryptoStreamMode.Write))
                {
                    using (StreamWriter swEncrypt = new StreamWriter(csEncrypt))
                    {
                        swEncrypt.Write(plainText);
                    }
                    encrypted = msEncrypt.ToArray();
                }
            }
            return encrypted;
        }

        public string decryption(byte[] cipherText)
        {
            if (cipherText == null || cipherText.Length <= 0)
                throw new ArgumentNullException("cipherText");
            if (m_bsKey == null || m_bsKey.Length <= 0)
                throw new ArgumentNullException("Key");
            if (m_bsIv == null || m_bsIv.Length <= 0)
                throw new ArgumentNullException("Key");
            string plaintext = null;
            m_rijAlg.Key = m_bsKey;
            m_rijAlg.IV = m_bsIv;
            ICryptoTransform decryptor = m_rijAlg.CreateDecryptor(m_rijAlg.Key, m_rijAlg.IV);
            using (MemoryStream msDecrypt = new MemoryStream(cipherText))
            {
                using (CryptoStream csDecrypt = new CryptoStream(msDecrypt, decryptor, CryptoStreamMode.Read))
                {
                    using (StreamReader srDecrypt = new StreamReader(csDecrypt))
                    {
                        plaintext = srDecrypt.ReadToEnd();
                    }
                }
            }
            return plaintext;
        }
    }
}
